<template>
  <n-card :header-style="{ padding: '10px', background: '#F1F5FF', marginBottom: '10px' }" ref="elementRef"
    style="min-height: 317px;">
    <template #header> {{ index }}.定向选择</template>
    <n-skeleton :repeat="8" text v-if="diect.loading"></n-skeleton>
    <n-empty description="请先至少选择一个账户" v-if="!account.accountCode && !diect.loading" style="margin-top: 40px">
    </n-empty>
    <!-- v-show="!diect.loading && account.accountCode" -->
    <x-form ref="formRef" v-model:model="form" :rules="rules" label-placement="top" label-width="140"
      v-show="!diect.loading && account.accountCode">
      <n-form-item label="引用定向模板" path="outTargetingId">
        <n-select v-model:value="form.outTargetingId" @click="getTargetingList" :options="outTargetingList"
          label-field="targeting_name" placeholder="请选择定向包" value-field="targeting_id"
          @update:value="updateOutTargetingId" />
      </n-form-item>
      <n-form-item label="地理位置" path="regions">
        <n-space vertical style="width: 100%">
          <!-- v-model="form.regions" @change="handleChangeRegions" -->
          <!-- <div v-for="item in targetingList[0] && targetingList[0].children">{{ item.regionName }}</div> -->
          <!-- {{ targetingList }} -->
          <el-cascader-panel v-model="expandMids" class="adgroup-region-selector" ref="cascaderPanelRef"
            :expandTrigger="false" style="width: fit-content"
            :props="{ value: 'id', label: 'regionName', checkStrictly: false, emitPath: false, multiple: false, expandTrigger: false }"
            :options="targetingList">
            <template v-slot="{ node, data }">
              <div style="margin-left: 0px" @click="doLeaf(node)">
                <n-checkbox :disabled="data.disabled" :indeterminate="regionIdMaps[node.value]?.indeterminate"
                  :checked="regionIdMaps[node.value]?.checked"
                  @update:checked="(v: any) => doCheck(node, v)"></n-checkbox>
                <span style="margin-left: 8px">{{ node.label }}</span>

              </div>
            </template>
          </el-cascader-panel>
          <!-- <n-checkbox>常住地</n-checkbox> -->
        </n-space>
      </n-form-item>
      <n-form-item label="地点类型" path="targeting.geo_location.location_types">

        <n-checkbox-group v-model:value="form.targeting.geo_location.location_types">
          <n-checkbox v-for="item in locationTypes" :value="item.value" :key="item.value">{{ item.label }}</n-checkbox>
        </n-checkbox-group>
      </n-form-item>
      <n-form-item label="年龄" path="targeting.age">
        <n-select v-model:value="form.targeting.age[0].min" :options="startAgeList" value-field="key" label-field="label"
          style="width: 160px" clearable placeholder="请选择" @update:value="changeAge('start')">
        </n-select>
        <span style="margin: 0 8px">至</span>
        <n-select v-model:value="form.targeting.age[0].max"
        @update:value="changeAge('end')"
        :options="endAgeList" value-field="key" label-field="label"
          style="width: 160px" clearable placeholder="请选择">
        </n-select>
      </n-form-item>
      <n-form-item label="性别" path="targeting.gender">
        <n-radio-group v-model:value="form.targeting.gender">
          <n-radio-button v-for="item in genderList" :key="item.value" :value="item.value" :label="item.label">{{
            item.label
            }}</n-radio-button>
        </n-radio-group>
      </n-form-item>
      <!-- <x-button type="primary" @click="validateForm">校验</x-button> -->
    </x-form>
    <CreateTargetingModal v-if="modal.show" :modal-data="modal" :account-code="account.accountCode"
      @success="createSuccess" />
  </n-card>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
import { XForm, XButton } from '@/components'
import { NCard, NFormItem, NSelect, NRadioGroup, NRadioButton, NCheckbox, useMessage, NSkeleton, NEmpty, NCheckboxGroup } from 'naive-ui'
import { computed, nextTick, onMounted, reactive, ref, watch, } from 'vue'
import { useStore } from '@/store'
import { getTargetingTagsList as getTargetingTagsListApi, getTargetingList as getTargetingListApi } from '@/api/intelligent';
import CreateTargetingModal from '@/views/advertising/ads/create/components/CreateTargetingModal.vue'

import { deepSearch } from '@/utils/deep.js'

// import { tree } from './m.ts';
defineProps({
  index: {
    type: Number
  }
})

const message = useMessage()
const store = useStore()
const position = computed(() => store.state.adv.modal.position)
const formRef = ref()
const expandMids = ref([]);
const targetingList = ref([])
const outTargetingList = ref([]);
const regionIdMaps = reactive<any>({
});

// targetingList.value = tree.data as any;
// initRegionIdMaps(targetingList.value);
// doLevelExand(1);

const China = '1156';




const locationTypes = computed(() => {
  // const
  const siteSetMap: any = {};
  position.value.siteSet.map(site => {
    siteSetMap[site] = 1;
  });
  // 自动版位 + 全版位
  if (position.value.siteSetType == '1' || (siteSetMap[113] && siteSetMap[102] && siteSetMap[116] && siteSetMap[100] && siteSetMap[101] && siteSetMap[27] && siteSetMap[28] && siteSetMap[15] && siteSetMap[21])) {
    return [{
      label: '常住地',
      value: 'LIVE_IN'
    }]
  }
  // 如果包含 微信视频号 / 微信朋友圈 / 微信公众号与小程序 只允许选择
  if (siteSetMap[113] || siteSetMap[102] || siteSetMap[121] || siteSetMap[116]) {
    return [{
      label: '常住且近期',
      value: 'LIVE_AND_RECENTLY'
    }, {
      label: '常住地',
      value: 'LIVE_IN'
    },]
  }
  return [{
    label: '近期到访',
    value: 'RECENTLY_IN'
  }, {
    label: '常住且近期',
    value: 'LIVE_AND_RECENTLY'
  }, {
    label: '常住地',
    value: 'LIVE_IN'
  }, {
    label: '旅行到访',
    value: 'TRAVEL_IN'
  }, {
    label: '曾经到访',
    value: 'VISITED_IN'
  }]
})


const diect = computed(() => store.state.adv.modal.diect)
const account = computed(() => (store.state.adv.accounts[0] || {}));
const ageList = computed(() => {
  const ageList = []
  for (let i = 18; i < 66; i++) {
    ageList.push({ key: i, label: i + '岁' })
  }
  ageList.unshift({ key: 14, label: 14 + '岁' })
  ageList.push({ key: 66, label: 66 + '岁及以上' })
  return ageList
});

const startAgeList = computed(() => {
    const max = form.value.targeting.age ? form.value.targeting.age[0].max : 100;

    return ageList.value.map((value:any) => {
      let key = value.key;
      return {
        ...value,
        disabled: key > max - 4
      }
    })
})
const endAgeList = computed(() => {
    const min = form.value.targeting.age ? form.value.targeting.age[0].min : 0;
    return ageList.value.map((value:any) => {
      let key = value.key;
      return {
        ...value,
        disabled: key === 18 ||  key < min + 4
      }
    })
});
function changeAge(type:string) {
  const min =  form.value.targeting.age ? form.value.targeting.age[0].min : 0;
  const max = form.value.targeting.age ? form.value.targeting.age[0].max : 100;
  if(type =='start' && Math.abs(min - max) < 4) {
    form.value.targeting.age[0].max = undefined;
  }

  if(type =='end' && Math.abs(min - max) < 4) {
    form.value.targeting.age[0].min = undefined;
  }
}
const genderList = ref([
  {
    value: '',
    label: '不限'
  },
  {
    value: 'MALE',
    label: '男'
  },
  {
    value: 'FEMALE',
    label: '女'
  }
])
const form = ref<any>({ targeting: diect.value.targeting, outTargetingName: undefined, outTargetingId: undefined, });
// const form = ref<any>({
//   outTargetingName: "",
//   outTargetingId: null,
//   ageBegin: 14,
//   locationTypes: diect.value.geo_location.location_types,

//   ageEnd: 66,
//   regions: [],
//   gender: ''
// })
const rules = ref({
  'targeting.geo_location.location_types': {
    type: 'array',
    required: true,
    trigger: ['change'],
    message: '请选择地点类型'
    // validator(_, value: any) {
    //   if () {
    //     return new Error(`请选择地点类型!`)
    //   }
    //   return true;
    // },
  },
  'targeting.regions': {
    type: 'array',
    required: true,
    trigger: ['change'],
    validator(_, value: any) {
      if (!regionIdMaps[China].checked) {
        return new Error(`请选择地理位置!`)
      }
      return true;
    },
    // message: '请选择地理位置'
  },
  'targeting.age': {
    required: true,
    // type: 'number',
    trigger: ['change'],
    validator(_:any, value: any) {
      if (value[0] && (!value[0].min || !value[0].max)) {
        return new Error(`请选择年龄!`)
      }
      return true;
    },
    // message: '请选择年龄'
  },
  // ageEnd: {
  //   required: true,
  //   type: 'number',
  //   trigger: ['change'],
  //   message: '请选择年龄'
  // },
  // gender: {
  //   required: true,
  //   trigger: ['change'],
  //   message: '请选择性别'
  // }
})


const modal = ref({
  show: false
});

async function defaultAction() {
  getTargetingList();
  if (targetingList.value.length) return;
  await getTargetingTagList();
  const regions: any = [];
  targetingList.value.map((target: any) => {
    if (target.id == China) {
      regions.push(target.id);
      target.children.map((item: any) => {
        if (!(item.regionName == '台湾省' || item.regionName == '澳门特别行政区' || item.regionName === '香港特别行政区')) {
          regions.push(item.id);
        }
      })
    };
  })
  const { checkExpandMaxDeepFirstPath } = updateRegionSelect(regions);
  expandMids.value = checkExpandMaxDeepFirstPath;
  nextTick(() => {
    doLevelExand(1);
  })

}



// 有数据更新时调用
watch(() => diect.value.onInfoUpdateAction, () => {
  // console.log('update');
  // form.value.targeting.locationTypes = diect.value.geo_location.location_types;
  form.value.targeting.geo_location.location_types = diect.value.targeting.geo_location.location_types
})




// 通过所有地域ids去选中
function updateRegionSelect(regions: any) {
  // 如果存在数据 默认设置中国为选中
  regions.length && (regionIdMaps[China].checked = true);
  regions.map((regionId: any) => {
    const oldRegion = regionIdMaps[regionId];
    regionIdMaps[regionId] = Object.assign({}, oldRegion, {
      checked: true,
      isOpenLeaf: false,
    })
  })
  // 选中的一级展开后首个最深的路径
  let checkExpandMaxDeepFirstPath: any = [];
  // 最深选中的节点
  let maxDeepCheckedNode: any = null;
  // 最深选中的节点
  let checkPath: any = [];
  deepSearch(targetingList.value, (item: any) => {
    const children = item.children || [];
    const mapNode = regionIdMaps[item.id];
    const checkedRegions = children.filter((node: any) => {
      return regionIdMaps[node.id].checked;
    });
    // 从idsMap找到选中的节点 判断是否更新 checkPath 路径
    if (mapNode.checked && ((item.s__value__ && item.s__value__.length) > checkPath.length)) {
      checkPath = item.s__value__;
      maxDeepCheckedNode = item;
    }
    // 设置父级的半选中状态
    mapNode.indeterminate = checkedRegions.length ? checkedRegions.length !== children.length : undefined;
  }, {
    key: 'id'
  })
  checkExpandMaxDeepFirstPath = [].concat([], checkPath);
  // 对路径继续处理
  if (maxDeepCheckedNode) {
    let firstChild = maxDeepCheckedNode.children ? maxDeepCheckedNode.children[0] : null;
    while (firstChild) {
      checkExpandMaxDeepFirstPath.push(firstChild.id);
      firstChild = firstChild.children ? firstChild.children[0] : null;
    }
  }
  return {
    checkPath,
    checkExpandMaxDeepFirstPath
  }
}

async function initForm() {
  store.commit('adv/TRIGGER_MODULE_LOADING', {
    name: 'diect',
  });
  form.value.targeting = diect.value.targeting;
  const regions = form.value.targeting.geo_location.regions;
  if (!targetingList.value.length) {
    await getTargetingTagList();
  }
  if (!outTargetingList.value.length) {
    await getTargetingList();
  }
  const { checkExpandMaxDeepFirstPath, checkPath } = updateRegionSelect(regions || []);
  expandMids.value = checkExpandMaxDeepFirstPath;
  nextTick(() => {
    doLevelExand(1);
    store.commit('adv/TRIGGER_MODULE_LOADING', {
      name: 'diect'
    })
  });
  form.value.outTargetingId = diect.value.outTargetingId;
}

watch(form.value, () => {
  const value = form.value;
  diect.value.outTargetingId = value.outTargetingId;
  diect.value.outTargetingName = value.outTargetingName;
},)
function createSuccess() {
  getTargetingTagList()
}
// 获取定向lib
async function getTargetingList() {
  if (!account.value.accountCode) return;
  if (outTargetingList.value.length) return;
  const { data } = await getTargetingListApi({
    accountCode: account.value.accountCode
  });
  // 设置定向id;
  diect.value.targetingAccountCode = account.value.accountCode;
  outTargetingList.value = data;
  return data;
}
const cascaderPanelRef = ref();
// 选中引用定向模板 Pendding
function updateOutTargetingId(val: any, opiton: any) {
  const targeting = opiton.targeting;

  form.value.targeting = diect.value.back(targeting);

  let regions = opiton.targeting.geo_location.regions;

  let isChinaRegin = regions.length == 1 && regions[0] == China;
  if(isChinaRegin) {
    const chinaRegin:any = targetingList.value.find((_:any) => _.id == China);
    chinaRegin && chinaRegin.children.map((item:any) => {
      regions.push(item.id)
    })
  }
  const regionsMap: any = {};
  regions.map((id: any) => {
    regionsMap[id] = 1;
  });
  let checkPath: any = []
  // 设置定向
  deepSearch(targetingList.value, (item: any) => {
    const id = item.id;
    const path = item.s__value__;
    // 如果命中则选中
    if (regionsMap[id]) {
      const current = regionIdMaps[id];
      // 路径上的全部选择一遍
      path.map((pathId: any) => {
        const oldRegion = regionIdMaps[pathId];
        regionIdMaps[pathId] = Object.assign({}, oldRegion, {
          checked: true,
        });
      });
      const children = item.children;
      // 查看子节点是否全部选中
      const checkedRegions = children.filter((node: any) => {
        return regionsMap[node.id];
      });
      current.indeterminate = checkedRegions.length ? checkedRegions.length !== children.length : undefined;
      // 从idsMap找到选中的节点 判断是否更新 checkPath 路径
      if (((item.s__value__ && item.s__value__.length) > checkPath.length)) {
        checkPath = item.s__value__;
      }
    } else {
      const oldRegion = regionIdMaps[id];
      regionIdMaps[id] = Object.assign({}, oldRegion, {
        checked: false,
        indeterminate: false,
      });
    }
  }, { key: 'id' });



}

function setNode(node: any, options: any) {

  Object.keys(options).map(key => {
    const value = options[key];
    // console.log()
    // node[key] = value;
    node[key] = value;
    // node.data[key] = value;
  })

}
// 首先触发checked
function doCheck(node: any, v: any) {
  const mapNode = regionIdMaps[node.value];
  if (node.data.disabled) return;
  setNode(mapNode, {
    checked: v,
    indeterminate: false,
  });
  // 下级的checked
  node.children.map((_: any) => {
    if (_.data.disabled) return;
    const mapNode = regionIdMaps[_.value];
    setNode(mapNode, {
      checked: v
    })
    if (mapNode.isOpenLeaf) {
      doCheck(_, v);
    }
  });

}
function syncParent(node: any) {
  let pathNodes = node.pathNodes;
  pathNodes.slice(0, pathNodes.length - 1).map((parent: any) => {
    const checkedNodes = parent.children.filter((node: any) => {
      const mapNode = regionIdMaps[node.value];
      return mapNode.checked;
    });
    const parentMapNode = regionIdMaps[parent.value];
    setNode(parentMapNode, {
      checked: checkedNodes.length != 0,
      indeterminate: checkedNodes.length != 0 ? checkedNodes.length != parent.children.length : false
    })
  })
}

function getPanel() {
  const ref = cascaderPanelRef.value;
  return ref;
}

// 将点击的节点leaf(激活) 未点击(激活)的节点不会默认勾选下级
function doLeaf(node: any) {
  const panel = getPanel();
  const diff = panel.menus.length - node.level;
  // 如果点击的级别与panel最大级超过一级，收回panel到点击的下一级
  if (diff > 1) {
    // panel.menus = panel.menus.slice(0, node.level + 1);
    const menu = panel.menuList[0];
    // console.log(menu, 'menu');
    menu && menu.panel.expandNode(node, false);
  }
  const mapNode = regionIdMaps[node.value];
  // 勾选下级所有节点
  if (!mapNode.isOpenLeaf && !mapNode.indeterminate) {
    doCheck(node, mapNode.checked);
  }
  setNode(mapNode, {
    isOpenLeaf: true
  })

  // 同步 check会早于leaf发生，所以同步写在doLeaf
  syncParent(node);

}

function doLevelExand(level: number) {
  expandMids.value = [China, 710000, 719900].slice(0, level) as any;
  nextTick(() => {
    const panel = getPanel();
    const max = level;
    while (level) {

      const menu = panel.menuList[max - level];
      if (menu) {
        const node = menu.nodes[0];
        node && menu.panel.expandNode(node, false);
      }
      level--;
    }

  })

  // const menu = panel.

}


function getChecks() {
  // 获取第一个菜单
  const regions: any = [];
  deepSearch(targetingList.value, (item: any) => {
    const mapNode = regionIdMaps[item.id];
    // 选中并且非部分选
    if (!mapNode.indeterminate && mapNode.checked) {
      regions.push(item.id);
      return 'stopnext';
    }
  });
  return regions;
}
// 初始化地域对应的id映射
/**
 *
 * @param data
 *
 */
function initRegionIdMaps(data: any) {
  deepSearch(data, (item: any, level: any) => {
    regionIdMaps[item.id] = {
      checked: false,
      indeterminate: false,
      isOpenLeaf: false,
    }
    if (item.regionName == '台湾省' || item.regionName == '澳门特别行政区' || item.regionName === '香港特别行政区') {
      item.disabled = false;
    }
  },)
}

// 获取地理位置标签
async function getTargetingTagList() {
  if (!account.value.accountCode) return;
  if (targetingList.value.length) return;
  const { data } = await getTargetingTagsListApi({
    accountCode: account.value.accountCode
  });
  initRegionIdMaps(data);
  targetingList.value = data;
}


/*
 * 表单数据校验
 * */
const elementRef = ref();
function validate() {
  const regions = getChecks();
  form.value.targeting.geo_location.regions = regions;
  diect.value.targeting = form.value.targeting;
  return new Promise<void>((resolve, reject) => {
    nextTick(() => {
      formRef.value?.validate(async (errors: any) => {
        if (!errors) {
          try {
            resolve()
          } catch (e) {
            reject()
          }
        } else {
          store.commit('adv/SCROLL_TO_ELEMENT', elementRef.value.$el)
          reject()
          console.log('errors', errors)
        }
      })

    })

  })
}

function getLoadInfo() {
  getTargetingList()
  // // 重置数据
  getTargetingTagList()
}

function getBackDisplay() {
  initForm()
}



defineExpose({
  defaultAction,
  getLoadInfo,
  getBackDisplay,
  validate,
  initForm
})
</script>
<style>
.el-cascader-menu {
  min-width: auto;
  max-width: 150px;
}
</style>
<style lang="scss">
.adgroup-region-selector {
  @keyframes slideOn {
    from {
      flex: 0;
    }

    to {
      flex: 100%;
    }
  }

  // max-width: 400px;
  &.el-cascader-panel {
    width: 100% !important;
    display: flex;

    .el-cascader-menu {
      transition: flex 0.3s;
      max-width: 100% !important;
      min-width: auto !important;
      width: 100% !important;
      flex: 1;
      animation: slideOn 0.3s ease-in forwards;
    }

  }

  .el-cascader-node {
    padding-left: 2px;

  }
}
</style>
